package com.panopset.io;

import static com.panopset.Util.dspmsg;
import static com.panopset.Util.getCanonicalPath;

import java.io.File;
import java.io.StringWriter;
import java.util.Collections;
import java.util.Map;
import java.util.TreeMap;
import java.util.Map.Entry;

import com.panopset.flywheel.Flywheel;

/**
 * Prepare properties file.
 *
 * Takes a source properties file and performs variable substitution to prepare
 * the target properties file.
 *
 * @author Karl Dinwiddie
 *
 */
public final class PrepProps {

    /**
     * @param s
     *            0 = Source, 1 = target.
     */
    public static void main(final String... s) {
        new PrepProps().go(new File(s[0]), new File(s[1]));
    }

    /**
     * @param s
     *            Source.
     * @param t
     *            Target.
     */
    void go(final File s, final File t) {
        dspmsg("source: " + getCanonicalPath(s));
        new FileProcessor(s, new FileAdaptor() {
            @Override
            public void process(
                    final FileProcessor processor, final String[] s) {
                PrepProps.this.absorb(s[0]);
            }
        }).exec();
        LockedWriter lw = new LockedWriter(t);
        for (Entry<String, String> e : map.entrySet()) {
            StringWriter sw = new StringWriter();
            sw.append(e.getKey());
            sw.append("=");
            sw.append(e.getValue());
            lw.writeln(sw.toString());
        }
        lw.close();
        dspmsg("target: " + getCanonicalPath(t));
    }

    /**
     * Map.
     */
    private final Map<String, String> map
        = Collections.synchronizedSortedMap(new TreeMap<String, String>());

    /**
     * Absorb a line.
     *
     * @param s String to absorb.
     */
    void absorb(final String s) {
        int i = s.indexOf("=");
        if (i > -1 && i < s.length()) {
            String key = s.substring(0, i);
            String val = s.substring(i + 1);
            map.put(key, process(val));
        }
    }

    /**
     * Process.
     *
     * @param val
     *            Value to process.
     * @return Processed value.
     */
    private String process(final String val) {
        return new Flywheel.Builder().map(map).input(new String[] {val})
                .construct().exec();
    }
}
